#pragma once
#include "Connection.hpp"
#include "Common.hpp"

class Channel : public Connection
{
public:
    Channel(int fd, const InetAddr &addr)
        : _fd(fd), _client_info(addr)
    {
        SetNonBlock(fd);
    }
#define SIZE 1024
    void Recver() override
    {
        LOG(LogLevel::DEBUG) << "进入到Channel Recver...";
        char buff[SIZE];
        while (true)
        {
            buff[0] = 0;
            ssize_t n = recv(_fd, buff, sizeof(buff) - 1, 0);
            if (n < 0)
            {
                if (errno == EAGAIN || errno == EWOULDBLOCK) // 非阻塞读完了
                {
                    break;
                }
                else if (errno == EINTR) // 信号中断了
                {
                    continue;
                }
                else
                {
                    Excepter();
                    return;
                }
            }
            else if (n == 0)
            {
                Connection::GetOwner()->DelConnection(_fd);
                LOG(LogLevel::INFO) << "client quit, sockfd: " << _fd;
                return;
            }
            else
            {
                buff[n] = 0;
                _inbuffer += buff;
            }
        }
        // 走到这里，这一轮已经读完了
        // 回调，交由应用层处理，返回响应的resp_str
        std::cout << "_inbuffer:" << std::endl;
        std::cout << _inbuffer;
        std::string resp_str = _handler(_inbuffer);
        _outbuffer += resp_str;
        // 立马发请求回去
        Sender();
    }

    void Sender() override
    {
        LOG(LogLevel::DEBUG) << "进入到Sender()";
        std::cout << "_outbuffer:" << std::endl;
        std::cout << _outbuffer;
        // _outbuffer非空，不断写
        while (!_outbuffer.empty())
        {
            ssize_t n = send(_fd, _outbuffer.c_str(), sizeof(_outbuffer), 0);
            if (n < 0)
            {
                if (errno == EAGAIN || errno == EWOULDBLOCK) // 写满了
                {
                    break;
                }
                else if (errno == EINTR) // 被信号中断了
                {
                    continue;
                }
                else
                {
                    Excepter();
                    return;
                }
            }
            else
            {
                _outbuffer.erase(0, n);
            }
        }
        // 走到这，一定是发送缓冲区满 或 写完了
        if (!_outbuffer.empty())
            Connection::GetOwner()->EnableWREvent(_fd, true, true); // 内核发送缓冲区写满了
        else
            Connection::GetOwner()->EnableWREvent(_fd, false, true); //_outbuffer写完了
    }

    void Excepter() override
    {
        Connection::GetOwner()->DelConnection(_fd);
        LOG(LogLevel::INFO) << "except has been solved, sockfd: " << _fd;
    }

    int GetFd() override
    {
        return _fd;
    }

    ~Channel()
    {
    }

private:
    int _fd;
    std::string _inbuffer;
    std::string _outbuffer;
    // 客户端信息
    InetAddr _client_info;
};